package com.fingard.dsp.bank.directbank.cib03;

import com.fingard.common.utils.json.JSONUtils;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.directbank.cib03.util.Base64;
import com.fingard.dsp.bank.directbank.cib03.util.Signature;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.text.StringHelper;
import com.fingard.util.DEHelper;
import com.fingard.util.DateHelper;
import sun.misc.BASE64Decoder;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

/**
 * 兴业汇收付历史明细获取
 *
 * @author fanghh
 * @date 2019/10/14
 */
public class CIB03Transaction extends CIB03Base implements ITransaction {
    @Override
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception {
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        retAts.writeStart();

        String tmpRespCode = "";
        String tmpRespInfo = "";

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req7516.actNum, "");
            if (actItem == null) {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo("未找到账号[" + p_req7516.actNum + "]商户配置信息,请检查'config/portfiles/CIB03/config.xml'中'actSet'节点相关配置!");
                retAts.writeEnd();
                return retAts;
            }

            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());
            tmpCalendarFrom.add(tmpCalendarFrom.DAY_OF_MONTH, 1);

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());
            tmpCalendarTo.add(tmpCalendarTo.DAY_OF_MONTH, 1);

            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;
            while (tmpIntDateFrom <= tmpIntDateTo && tmpRespCode.length() == 0) {
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }

                // 月内日期段内查询
                int tmpDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                int tmpDateTo = Integer.parseInt(Format.Date8Format.format(tmpClndrStepTo.getTime()));

                while (tmpDateFrom <= tmpDateTo) {
                    HashMap<String, String> postMapParams = new HashMap<String, String>();
                    postMapParams.put("version", "1.0.2");
                    postMapParams.put("mchtId", actItem.merchantId);
                    postMapParams.put("signType", "RSA");
                    postMapParams.put("serialNo", getQryTransID());
                    postMapParams.put("transTime", Format.DateTime14Format.format(new Date()));

                    Calendar checkDate = Calendar.getInstance();
                    checkDate.setTime(tmpCalendarFrom.getTime());
                    postMapParams.put("fileDate", Format.Date8Format.format(checkDate.getTime()));
                    postMapParams.put("mac", generateMAC(postMapParams, actItem));

                    String tmpStrRet = sendDataToBank(JSONUtils.map2JSON(postMapParams), "qryTransaction");

                    if (StringHelper.hasAnyChar(tmpStrRet)) {
                        if (tmpStrRet.indexOf("{") >= 0) {
                            HashMap<String, String> tmpJsonRet = JSONUtils.json2Map(tmpStrRet);

                            String tmpRetCode = tmpJsonRet.get("respCode");
                            if ("E0000".equals(tmpRetCode)) {
                                // 应答返回的加密对账文件内容
                                String encryptCheckFileContent = tmpJsonRet.get("fileContent");
                                WriteBankLogLn2("银行响应文件内容密文:\r\n" + encryptCheckFileContent);
                                byte[] decompressBytes = null;
                                // 应答返回的秘钥串
                                String aesKey = tmpJsonRet.get("aesKey");
                                if (StringHelper.hasAnyChar(aesKey)) {
                                    // 用商户私钥证书对秘钥串进行解密
                                    String key = Signature.decoderByCFCA(aesKey, actItem.ownKeyStorePath, actItem.ownKeyPassword);
                                    WriteBankLogLn("解密后秘钥串aesKe:" + key);

                                    // 用AES给文件内容解密
                                    byte[] fileContent = Signature.AESDecode(encryptCheckFileContent, key);
                                    // 用Base64给文件内容转码
                                    byte[] b = Base64.decode(new String(fileContent, "UTF-8").toCharArray());
                                    // 对文件内容进行解压缩
                                    decompressBytes = DEHelper.uncompress(b);
                                } else {
                                    decompressBytes = DEHelper.uncompress(new BASE64Decoder().decodeBuffer(encryptCheckFileContent));
                                }
                                String tmpFileContentRet = new String(decompressBytes, getCharset());
                                WriteBankLogLn2("银行响应对账单内容:\r\n" + tmpFileContentRet);

                                String fileDetailContent = tmpFileContentRet.substring(tmpFileContentRet.indexOf('\n') + 1);
                                if (StringHelper.hasAnyChar(fileDetailContent)) {
                                    String[] fileLine = fileDetailContent.split("\n");
                                    for (String eachLine : fileLine) {
                                        if (eachLine == null) {
                                            continue;
                                        }
                                        String[] values = eachLine.split("\\|");

                                        RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();

                                        tmpRetDetail.actNum = values[0].trim();

                                        tmpRetDetail.tranDate = Format.Date10Format.format(Format.Date8Format.parse(values[1].trim()));// 格式yyyy-MM-dd
                                        tmpRetDetail.tranTime = Format.DateTimeFormat.format(Format.DateTime14Format.parse(values[1].trim() + values[2].trim()));// 格式"yyyy-MM-dd HH:mm:ss"
                                        tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                        tmpRetDetail.tranAmt = values[7].trim();
                                        tmpRetDetail.accBal = values[6].trim();
                                        String bkDcFlag = values[9].trim();
                                        if ("0".equals(bkDcFlag)) {
                                            tmpRetDetail.cdFlag = "1";
                                        } else if ("1".equals(bkDcFlag)) {
                                            tmpRetDetail.cdFlag = "2";
                                        } else {
                                            tmpRespCode = "-1";
                                            tmpRespInfo = "借贷标志有误，值：" + bkDcFlag;
                                            break;
                                        }

                                        if (values.length > 13) {
                                            tmpRetDetail.recAccNum = values[13].trim();
                                            tmpRetDetail.oriBizInfo = values[14].trim();
                                            tmpRetDetail.oriBizType = values[15].trim();
                                            tmpRetDetail.oriBizTime = values[16].trim();
                                        }

                                        if (values.length > 12) {
                                            tmpRetDetail.usage = values[12].trim();
                                            tmpRetDetail.comment = values[12].trim();
                                            tmpRetDetail.abstr = pickupAbstr(values[12].trim());
                                        }

                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                } else {
                                    tmpRespCode = "0";
                                    tmpRespInfo = "交易为空！";
                                }
                            }
                        }
                    }

                    tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                    tmpDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                }

                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        if ("-1".equals(tmpRespCode)) {
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空!");
        }

        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception {
        Req7516HisTrans tmpReq7516 = new Req7516HisTrans(p_req7515.reqHeader);

        tmpReq7516.actArea = p_req7515.actArea;
        tmpReq7516.actCur = p_req7515.actCur;
        tmpReq7516.actNum = p_req7515.actNum;

        String tmpDateNow = Format.Date8Format.format(new Date());
        tmpReq7516.dateFrom = tmpDateNow;
        tmpReq7516.dateTo = tmpDateNow;

        return d_7516_HisTrans(tmpReq7516);
    }
}